package com.jlg.search;

import java.util.HashMap;
import java.util.Map;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;

import com.julewa.loading.SystemUtils;


public class BeanInfo {
	private class PropertyInfo{
		private String name;
		private Class<?> type;
		private java.lang.reflect.Method method = null;
		private java.lang.reflect.Field field = null;
		private Field.Store store = null;
		private Field.Index index = null;
		private boolean init(SEARCH search){
			if(search == null)return false;
			index = Field.Index.NOT_ANALYZED;
			if(String.class.equals(type) && search.parse()){
				index = Field.Index.ANALYZED;
			}
			if(search.store()){
				store = Field.Store.YES;
			}else{
				store = Field.Store.NO;
			}
			return true;
		}
		public PropertyInfo(java.lang.reflect.Method method){
			this.type = method.getReturnType();
			if(!init(method.getAnnotation(SEARCH.class)))return;
			this.name = SystemUtils.getPropertyName(method);
			if(name == null)return;
			this.method = method;
		}
		public PropertyInfo(java.lang.reflect.Field field){
			this.type = field.getType();
			if(!init(field.getAnnotation(SEARCH.class)))return;
			this.name = field.getName();
			this.field = field;
		}
		public String getName(){
			return name;
		}
		public void parse(Document doc, Object obj) throws Exception{
			if(method == null){
				obj = field.get(obj);
			}else{
				obj = method.invoke(obj);
			}
			doc.add(new Field(name, obj==null?"":obj.toString(), store, index));
		}
	}
	private Map<String, PropertyInfo> properties = new HashMap<String, PropertyInfo>();
	public BeanInfo(Class<?> clazz){
		java.lang.reflect.Field fs[] = clazz.getFields();
		for(java.lang.reflect.Field f:fs){
			PropertyInfo p = new PropertyInfo(f);
			if(p.getName() == null)continue;
			properties.put(p.getName(), p);
		}
		java.lang.reflect.Method ms[] = clazz.getMethods();
		for(java.lang.reflect.Method m:ms){
			PropertyInfo p = new PropertyInfo(m);
			if(p.getName() == null)continue;
			properties.put(p.getName(), p);
		}
	}
	
	public Document createDocument(Object obj){
		//if(obj == null)return null;
		if(properties.isEmpty())return null;
		Document doc = new Document();
		try{
			for(PropertyInfo p:properties.values()){
				p.parse(doc, obj);
			}
		}catch(Exception ex){
			return null;
		}
		return doc;
	}
}
